<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>mybatis3学习笔记 | rongshen</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/highlight.css">

  
  <meta name="description" content="个人学习笔记mybatis">
<meta property="og:type" content="article">
<meta property="og:title" content="mybatis3学习笔记">
<meta property="og:url" content="http://example.com/2020/07/26/mybatis3%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="rongshen">
<meta property="og:description" content="个人学习笔记mybatis">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a1.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a2.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a3.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a4.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a5.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a6.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a7.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a8.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a9.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a10.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a11.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a12.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a13.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a14.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a15.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a16.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a17.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a18.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a19.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a20.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a21.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a22.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a23.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/20726a24.png">
<meta property="article:published_time" content="2020-07-26T07:14:07.000Z">
<meta property="article:modified_time" content="2021-05-07T06:41:52.898Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="mybatis">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://cdn.rongshen2020.com/20726a1.png"><meta name="generator" content="Hexo 6.1.0"></head>

<body>
  <div id="wrapper">
    <header id="header">
  <h1 id="title">
    <a href="/">rongshen</a>
  </h1>
  <nav>
    
    
      
      <a class="nav-link" href="/">Home</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/archives">Archives</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" target="_blank" rel="noopener" href="https://github.com/Aaron-boom">Github</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/2020/04/13/About-Me/">About</a>
    
    
  </nav>
</header>

    <div id="content">
      <article id="post-mybatis3学习笔记" class="article article-type-post" itemprop="blogPost" itemscope>
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h2 class="article-title" itemprop="headline name">
      mybatis3学习笔记
    </h2>
  


        <div class="article-meta">
          <time class="article-date" datetime="2020-07-26T07:14:07.000Z" itemprop="datePublished">2020-07-26</time>

          
        </div>
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
      
        <blockquote>
<p>个人学习笔记mybatis</p>
</blockquote>
<span id="more"></span>

<h1 id="1、简介"><a href="#1、简介" class="headerlink" title="1、简介"></a>1、简介</h1><p>中文文档：<a target="_blank" rel="noopener" href="https://mybatis.org/mybatis-3/zh/getting-started.html">https://mybatis.org/mybatis-3/zh/getting-started.html</a></p>
<h2 id="1-1、什么是MyBatis："><a href="#1-1、什么是MyBatis：" class="headerlink" title="1.1、什么是MyBatis："></a>1.1、什么是MyBatis：</h2><ul>
<li><p>MyBatis 是一款优秀的<strong>持久层框架</strong>，它支持自定义 SQL、存储过程以及高级映射。</p>
</li>
<li><p>MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。</p>
</li>
<li><p>MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO（Plain Old  Java Objects，普通老式 Java 对象）为数据库中的记录。</p>
</li>
<li><p>maven仓库：</p>
<pre><code class="java">&lt;!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mybatis&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis&lt;/artifactId&gt;
    &lt;version&gt;3.5.5&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
</li>
</ul>
<h2 id="1-2、持久层："><a href="#1-2、持久层：" class="headerlink" title="1.2、持久层："></a>1.2、持久层：</h2><p>数据持久化：</p>
<ul>
<li>持久化就是将程序的数据在持久状态和瞬时状态转化的过程。</li>
</ul>
<h1 id="2、HelloMybatis"><a href="#2、HelloMybatis" class="headerlink" title="2、HelloMybatis"></a>2、HelloMybatis</h1><ul>
<li><p>搭建环境（数据库）——》导入mybatis——》编写代码——》测试！</p>
</li>
<li><p>项目结构：<br><img src="http://cdn.rongshen2020.com/20726a1.png"></p>
</li>
</ul>
<ol>
<li><p>新建一个maven项目，删除src目录，建立module项目，导入maven依赖：</p>
<pre><code class="java">&lt;!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.mybatis&lt;/groupId&gt;
    &lt;artifactId&gt;mybatis&lt;/artifactId&gt;
    &lt;version&gt;3.5.5&lt;/version&gt;
    &lt;/dependency&gt;
&lt;!-- https://mvnrepository.com/artifact/junit/junit --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;junit&lt;/groupId&gt;
    &lt;artifactId&gt;junit&lt;/artifactId&gt;
    &lt;version&gt;4.12&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
&lt;!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;mysql&lt;/groupId&gt;
    &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
    &lt;version&gt;5.1.47&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
</li>
<li><p>创建一个子模块，编写mybatis的核心配置文件和编写mybatis的工具类：</p>
<ul>
<li>mybatis-config.xml：</li>
</ul>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE configuration
        PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-config.dtd&quot;&gt;

&lt;configuration&gt;

    &lt;environments default=&quot;development&quot;&gt;
        &lt;environment id=&quot;development&quot;&gt;
            &lt;transactionManager type=&quot;JDBC&quot;/&gt;
            &lt;dataSource type=&quot;POOLED&quot;&gt;
                &lt;property name=&quot;driver&quot; value=&quot;com.mysql.jdbc.Driver&quot;/&gt;
                &lt;property name=&quot;url&quot; value=&quot;jdbc:mysql://localhost:3306/mybatistest?useSSL=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8&quot;/&gt;
                &lt;property name=&quot;username&quot; value=&quot;root&quot;/&gt;
                &lt;property name=&quot;password&quot; value=&quot;root&quot;/&gt;
            &lt;/dataSource&gt;
        &lt;/environment&gt;
    &lt;/environments&gt;

    &lt;mappers&gt;
        &lt;mapper resource=&quot;UserMapper.xml&quot;/&gt;
    &lt;/mappers&gt;
&lt;/configuration&gt;
</code></pre>
<ul>
<li>MybatisUtils工具类：</li>
</ul>
<pre><code class="JAVA">package com.aaron.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MybatisUtils &#123;
    private static SqlSessionFactory sqlSessionFactory;

    static &#123;
        try &#123;
            //使用mybatis第一步，获取sqlSessionFactory对象
            String resource = &quot;mybatis-config.xml&quot;;
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        &#125; catch (IOException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;

    //既然有了SqlSessionFactory,顾名思义，
    // 我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    // 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    public static SqlSession getSqlSession()&#123;
        return sqlSessionFactory.openSession();
    &#125;

&#125;
</code></pre>
</li>
</ol>
<h2 id="2-1、编写代码："><a href="#2-1、编写代码：" class="headerlink" title="2.1、编写代码："></a>2.1、编写代码：</h2><ul>
<li><p>实体类User：</p>
<pre><code class="java">package com.aaron.pojo;

public class User &#123;
    private int id;
    private String name;
    private String pwd;

    public User() &#123;
    &#125;

    public User(int id, String name, String pwd) &#123;
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    &#125;

    public int getId() &#123;
        return id;
    &#125;

    public void setId(int id) &#123;
        this.id = id;
    &#125;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    public String getPwd() &#123;
        return pwd;
    &#125;

    public void setPwd(String pwd) &#123;
        this.pwd = pwd;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;User&#123;&quot; +
                &quot;id=&quot; + id +
                &quot;, name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, pwd=&#39;&quot; + pwd + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
</li>
<li><p>dao接口：</p>
<pre><code class="java">package com.aaron.dao;

import com.aaron.pojo.User;

import java.util.List;

public interface UserDao &#123;
   public List&lt;User&gt; getUserList();
&#125;
</code></pre>
</li>
<li><p>接口实现类，由原来的UserDaoImpl.java变成了UserMapper.xml文件了：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;
    
//这里的id就像接口里要实现的方法名，resultType是执行sql语句后的返回值类型。里面写好sql语句。
&lt;mapper namespace=&quot;com.aaron.dao.UserDao&quot;&gt;
    &lt;select id=&quot;getUserList&quot; resultType=&quot;com.aaron.pojo.User&quot;&gt;
        select * from mybatistest.user;
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
</li>
<li><p>测试类：</p>
<pre><code class="java">package com.aaron.dao;

import com.aaron.pojo.User;
import com.aaron.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest &#123;

    @Test
    public void test()&#123;
        //第一步，获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行SQL
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List&lt;User&gt; userList = userDao.getUserList();
        for (User user : userList) &#123;
            System.out.println(user);
        &#125;
        //关闭SqlSession
        sqlSession.close();
    &#125;

&#125;
</code></pre>
</li>
<li><p>测试结果：</p>
<p><img src="http://cdn.rongshen2020.com/20726a2.png" alt="image-20200721203459936"></p>
</li>
</ul>
<h1 id="3、CRUD"><a href="#3、CRUD" class="headerlink" title="3、CRUD"></a>3、CRUD</h1><p>C：Create增加，R：Retrieve查询，U：Update修改，D：Delete删除。</p>
<h2 id="3-1、namespace："><a href="#3-1、namespace：" class="headerlink" title="3.1、namespace："></a>3.1、namespace：</h2><p>namespace中的包名要和dao&#x2F;mapper接口的包名一致；</p>
<ul>
<li>UserMapper.xml：</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/20726a3.png" alt="image-20200723124353020"></p>
<h2 id="3-2、select、insert、update、delete："><a href="#3-2、select、insert、update、delete：" class="headerlink" title="3.2、select、insert、update、delete："></a>3.2、select、insert、update、delete：</h2><p>写起来很简单，之前的pojo实体类和utils工具类以及mybatis-config.xml配置文件都不用改变。主要改变的是dao层的接口类和UserMapper.xml配置文件：</p>
<p><img src="http://cdn.rongshen2020.com/20726a4.png" alt="image-20200723130502497"></p>
<ul>
<li><p>dao层里面的接口UserDao.xml：</p>
<pre><code class="java">package com.aaron.dao;

import com.aaron.pojo.User;

import java.util.List;

public interface UserDao &#123;
   //获取全部用户
   public List&lt;User&gt; getUserList();

   //根据id查询用户
   User getUser(int userId);

   //插入用户
   Integer addUser(User user);

   //修改用户
   Integer updateUser(User user);

   //根据id删除用户
   Integer deleteUser(int id);
&#125;
</code></pre>
</li>
<li><p>UserMapper.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;

&lt;mapper namespace=&quot;com.aaron.dao.UserDao&quot;&gt;
    &lt;select id=&quot;getUserList&quot; resultType=&quot;com.aaron.pojo.User&quot;&gt;
        select * from mybatistest.user;
    &lt;/select&gt;

    &lt;select id=&quot;getUser&quot; parameterType=&quot;int&quot; resultType=&quot;com.aaron.pojo.User&quot;&gt;
        select * from mybatistest.user where id = #&#123;userId&#125;
    &lt;/select&gt;

    &lt;select id=&quot;addUser&quot; parameterType=&quot;com.aaron.pojo.User&quot;&gt;
        insert into mybatistest.user (id, name, pwd) values (#&#123;id&#125;,#&#123;name&#125;,#&#123;pwd&#125;);
    &lt;/select&gt;

    &lt;select id=&quot;updateUser&quot; parameterType=&quot;com.aaron.pojo.User&quot;&gt;
        update mybatistest.user set name=#&#123;name&#125;,pwd=#&#123;pwd&#125; where id=#&#123;id&#125;
    &lt;/select&gt;

    &lt;select id=&quot;deleteUser&quot;&gt;
        delete from mybatistest.user where id=#&#123;id&#125;
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
</li>
<li><p>测试类：</p>
<pre><code class="java">package com.aaron.dao;

import com.aaron.pojo.User;
import com.aaron.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest &#123;

    @Test
    public void test()&#123;
        //第一步，获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行SQL
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List&lt;User&gt; userList = userDao.getUserList();
        for (User user : userList) &#123;
            System.out.println(user);
        &#125;
        //关闭SqlSession
        sqlSession.close();
    &#125;

    @Test
    public void test1()&#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user = mapper.getUser(4);
        System.out.println(user);
        sqlSession.close();
    &#125;

    //增删改需要提交事务
    @Test
    public void test2()&#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);

        Integer flag = mapper.addUser(new User(7,&quot;哈哈&quot;,&quot;12345&quot;));
        System.out.println(flag);
        sqlSession.commit();

        sqlSession.close();
    &#125;

    @Test
    public void test3()&#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Integer flag = mapper.updateUser(new User(4,&quot;夏天&quot;,&quot;123dssdd&quot;));
        System.out.println(flag);
        sqlSession.commit();
        sqlSession.close();
    &#125;

    @Test
    public void test4()&#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Integer flag = mapper.deleteUser(7);
        System.out.println(flag);
        sqlSession.commit();
        sqlSession.close();
    &#125;
&#125;
</code></pre>
</li>
</ul>
<h2 id="3-3、map传递参数："><a href="#3-3、map传递参数：" class="headerlink" title="3.3、map传递参数："></a>3.3、map传递参数：</h2><p>假设我们的实体类，或者数据库中的表、字段或者参数过多，我们应当考虑使用Map。</p>
<ul>
<li>实体类：</li>
</ul>
<pre><code class="java">//传递map参数
User addUser2(Map&lt;String,Object&gt; map);
</code></pre>
<ul>
<li>配置文件UserMapper.xml：</li>
</ul>
<pre><code class="java">&lt;select id=&quot;addUser2&quot; parameterType=&quot;map&quot;&gt;
    insert into mybatistest.user (id, name, pwd) values (#&#123;id&#125;,#&#123;name&#125;,#&#123;pwd&#125;);
&lt;/select&gt;
</code></pre>
<ul>
<li>测试时：</li>
</ul>
<pre><code class="java">@Test
    public void test5()&#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
        map.put(&quot;id&quot;,7);
        map.put(&quot;name&quot;,&quot;夏天天1号&quot;);
        map.put(&quot;pwd&quot;,&quot;123456&quot;);
        mapper.addUser2(map);
        sqlSession.commit();
        sqlSession.close();
    &#125;
</code></pre>
<p><strong>3种情况：</strong></p>
<ul>
<li>Map传递参数，直接在sql中取出key即可！</li>
<li>对象传递参数，直接在sql中取对象的属性即可。</li>
<li>只有一个基本类型参数的，可以直接在sql中取到。</li>
</ul>
<h2 id="3-4、模糊查询："><a href="#3-4、模糊查询：" class="headerlink" title="3.4、模糊查询："></a>3.4、模糊查询：</h2><ol>
<li><p>java执行代码的时候，传递通配符<code>% %</code>。</p>
<p><img src="http://cdn.rongshen2020.com/20726a5.png" alt="image-20200723144008235"></p>
</li>
<li><p>sql注入问题一览：</p>
<pre><code class="java">select * from user where id = ?;
select * from user where id = 1;
与
select * from user where id = 1 or 1 = 1;
</code></pre>
</li>
<li><p>模糊查询实例：</p>
<ul>
<li><p>实体类的方法：</p>
<pre><code class="java">//模糊查询，根据名字
List&lt;User&gt; getUserLike(String name);
</code></pre>
</li>
<li><p>配置文件UserMapper.xml：</p>
<pre><code class="java">&lt;select id=&quot;getUserLike&quot; resultType=&quot;com.aaron.pojo.User&quot;&gt;
    select * from mybatistest.user where name like #&#123;name&#125;
&lt;/select&gt;
</code></pre>
</li>
<li><p>测试类：</p>
<pre><code class="java">@Test
public void test6()&#123;
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    List&lt;User&gt; userList = mapper.getUserLike(&quot;%夏%&quot;);
    for (User user : userList) &#123;
        System.out.println(user);
    &#125;
    sqlSession.close();
&#125;
</code></pre>
</li>
</ul>
</li>
</ol>
<h1 id="4、配置之属性优化"><a href="#4、配置之属性优化" class="headerlink" title="4、配置之属性优化"></a>4、配置之属性优化</h1><blockquote>
<p>注意里面的属性书写是有先后之分的：(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)”。注意哈，这都是写在mybatis-config.xmll文件中的。</p>
</blockquote>
<h2 id="4-1、核心配置mybatis-config-xml："><a href="#4-1、核心配置mybatis-config-xml：" class="headerlink" title="4.1、核心配置mybatis-config.xml："></a>4.1、核心配置mybatis-config.xml：</h2><ul>
<li><p>mybatis-config.xml配置文件中包含了会深深影响mybatis行为的设置和属性信息：</p>
<pre><code class="java">properties（属性）
settings（设置）
typeAliases（类型别名）
typeHandlers（类型处理器）
objectFactory（对象工厂）
plugins（插件）
environments（环境配置）
environment（环境变量）
transactionManager（事务管理器）
dataSource（数据源）
databaseIdProvider（数据库厂商标识）
mappers（映射器）
</code></pre>
</li>
</ul>
<h2 id="4-2、环境配置（environment）："><a href="#4-2、环境配置（environment）：" class="headerlink" title="4.2、环境配置（environment）："></a>4.2、环境配置（environment）：</h2><p>mybatis可以配置成适应多种环境。</p>
<p><strong>不过要记住：尽管可以配置多个环境，但每个SqlSessionFactory实例只能选择一种环境。</strong></p>
<p>学会使用配置多套环境运行。</p>
<p>mybatis默认的事务管理器就是JDBC，连接池POOLED。</p>
<h2 id="4-3、properties（属性）："><a href="#4-3、properties（属性）：" class="headerlink" title="4.3、properties（属性）："></a>4.3、properties（属性）：</h2><p>我们可以通过properti属性来实现引用配置文件。这些属性可以在外部进行配置，并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性，也可以在 properties 元素的子元素中设置。【db.properties】</p>
<ol>
<li><p>编写db.properties配置文件：</p>
<pre><code class="java">driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatistest?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8
username=root
password=root
</code></pre>
</li>
<li><p>在核心配置文件mybatis-config.xml中引入：</p>
<ul>
<li>直接引入外部文件：</li>
</ul>
<pre><code class="java">&lt;properties resource=&quot;db.properties&quot;/&gt;
</code></pre>
<ul>
<li>在其中可以增加属性配置：</li>
</ul>
<pre><code class="java">&lt;properties resource=&quot;db.properties&quot;&gt;
   &lt;property name=&quot;password&quot; value=&quot;12345&quot;/&gt;
&lt;/properties&gt;
</code></pre>
<ul>
<li>如果既有外部配置文件，又配置了相同的属性，优先使用外部配置文件里面的属性。</li>
</ul>
</li>
</ol>
<h2 id="4-4、类型别名（typeAliases）："><a href="#4-4、类型别名（typeAliases）：" class="headerlink" title="4.4、类型别名（typeAliases）："></a>4.4、类型别名（typeAliases）：</h2><ol>
<li>类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置，意在降低冗余的<strong>全限定类名</strong>书写。例如：</li>
</ol>
<pre><code class="java">&lt;typeAliases&gt;
    &lt;typeAlias type=&quot;com.aaron.pojo.User&quot; alias=&quot;user&quot;/&gt;
&lt;/typeAliases&gt;
</code></pre>
<p>那么在UserMapper.xml中使用时：</p>
<p><img src="http://cdn.rongshen2020.com/20726a6.png" alt="image-20200723182221949"></p>
<ol start="2">
<li><p>也可以指定一个包名，MyBatis 会在包名下面搜索需要的 Java Bean，扫描实体类的包，他的默认名就为这个类的类名，首字母小写！</p>
<pre><code class="java">&lt;typeAliases&gt;
  &lt;package name=&quot;com.aaron.pojo.User&quot;/&gt;
&lt;/typeAliases&gt;
    
使用时就是parameterType=&quot;user&quot;，类名的首字母小写即可。
</code></pre>
</li>
</ol>
<p><strong>总结说明：</strong>在实体类比较少的时候，使用第一种方式。如果实体类十分多，建议使用第二种。第一种可以diy别名，第二种则不行，如果非要改，需要在实体上增加注解。</p>
<pre><code class="java">@Alias(&quot;user1&quot;)
public class User &#123;
    ...
</code></pre>
<ul>
<li>别名参考：下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的，注意，为了应对原始类型的命名重复，采取了特殊的命名风格。</li>
</ul>
<table>
<thead>
<tr>
<th>别名</th>
<th>映射的类型</th>
</tr>
</thead>
<tbody><tr>
<td>_byte</td>
<td>byte</td>
</tr>
<tr>
<td>_long</td>
<td>long</td>
</tr>
<tr>
<td>_short</td>
<td>short</td>
</tr>
<tr>
<td>_int</td>
<td>int</td>
</tr>
<tr>
<td>_integer</td>
<td>int</td>
</tr>
<tr>
<td>_double</td>
<td>double</td>
</tr>
<tr>
<td>_float</td>
<td>float</td>
</tr>
<tr>
<td>_boolean</td>
<td>boolean</td>
</tr>
<tr>
<td>string</td>
<td>String</td>
</tr>
<tr>
<td>byte</td>
<td>Byte</td>
</tr>
<tr>
<td>long</td>
<td>Long</td>
</tr>
<tr>
<td>short</td>
<td>Short</td>
</tr>
<tr>
<td>int</td>
<td>Integer</td>
</tr>
<tr>
<td>integer</td>
<td>Integer</td>
</tr>
<tr>
<td>double</td>
<td>Double</td>
</tr>
<tr>
<td>float</td>
<td>Float</td>
</tr>
<tr>
<td>boolean</td>
<td>Boolean</td>
</tr>
<tr>
<td>date</td>
<td>Date</td>
</tr>
<tr>
<td>decimal</td>
<td>BigDecimal</td>
</tr>
<tr>
<td>object</td>
<td>Object</td>
</tr>
<tr>
<td>map</td>
<td>Map</td>
</tr>
<tr>
<td>hashmap</td>
<td>HashMap</td>
</tr>
<tr>
<td>list</td>
<td>List</td>
</tr>
<tr>
<td>arraylist</td>
<td>ArrayList</td>
</tr>
<tr>
<td>collection</td>
<td>Collection</td>
</tr>
<tr>
<td>iterator</td>
<td>Iterator</td>
</tr>
</tbody></table>
<h2 id="4-5、设置（settings）："><a href="#4-5、设置（settings）：" class="headerlink" title="4.5、设置（settings）："></a>4.5、设置（settings）：</h2><p><img src="http://cdn.rongshen2020.com/20726a7.png" alt="image-20200723200701175"></p>
<p><img src="http://cdn.rongshen2020.com/20726a8.png" alt="image-20200723200728188"></p>
<pre><code class="java">&lt;settings&gt;
  &lt;setting name=&quot;cacheEnabled&quot; value=&quot;true&quot;/&gt;
  &lt;setting name=&quot;lazyLoadingEnabled&quot; value=&quot;true&quot;/&gt;
&lt;/settings&gt;
</code></pre>
<h2 id="4-6、其他配置："><a href="#4-6、其他配置：" class="headerlink" title="4.6、其他配置："></a>4.6、其他配置：</h2><ul>
<li>typeHandlers（类型处理器）</li>
<li>objectFactory（对象工厂）</li>
<li>plugins（插件）：<ul>
<li>mybatis-generator-core</li>
<li>mybatis-plus</li>
<li>通用mapper</li>
</ul>
</li>
</ul>
<h2 id="4-7、映射器（mappers）："><a href="#4-7、映射器（mappers）：" class="headerlink" title="4.7、映射器（mappers）："></a>4.7、映射器（mappers）：</h2><p>我们需要告诉 MyBatis 到哪里去找到 SQL 映射语句，就是UserMapper.xml这样的文件里定义的。 在自动查找资源方面，Java 并没有提供一个很好的解决方案，所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用，或完全限定资源定位符（包括 <code>file:///</code> 形式的 URL），或类名和包名等。</p>
<p><strong>MapperRegistry：注册绑定我们的Mapper文件。每一个Mapper.xml都需要在mybatis的核心配置文件里面注册。</strong></p>
<ul>
<li><p>方式一：</p>
<pre><code class="java">&lt;mappers&gt;
    &lt;mapper resource=&quot;com/aaron/dao/UserMapper.xml&quot;/&gt;
&lt;/mappers&gt;
</code></pre>
</li>
<li><p>方式二：</p>
<pre><code class="java">&lt;mappers&gt;
    &lt;mapper class=&quot;com.aaron.dao.UserMapper&quot;/&gt;
&lt;/mappers&gt;
</code></pre>
<ul>
<li>使用这种方式的注意点：<ul>
<li>接口和它的Mapper配置文件必须同名。</li>
<li>接口和他的Mapper配置文件必须在同一包下。</li>
</ul>
</li>
</ul>
</li>
<li><p>方式三：</p>
<pre><code class="java">&lt;!-- 将包内的映射器接口实现全部注册为映射器,--&gt;
&lt;mappers&gt;
  &lt;package name=&quot;com.aaron.dao&quot;/&gt;
&lt;/mappers&gt;
</code></pre>
<ul>
<li>使用这种方式的注意点：<ul>
<li>接口和它的Mapper配置文件必须同名。</li>
<li>接口和他的Mapper配置文件必须在同一包下。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="4-8、生命周期与作用域："><a href="#4-8、生命周期与作用域：" class="headerlink" title="4.8、生命周期与作用域："></a>4.8、生命周期与作用域：</h2><p>生命周期和作用域是至关重要的，因为错误的使用会导致非常严重的并发问题。</p>
<p><strong>SqlSessionFactoryBuilder:</strong></p>
<ul>
<li>这个类可以被实例化、使用和丢弃，一旦创建了 SqlSessionFactory，就不再需要它了。所以可以将其设置为<strong>局部变量。</strong></li>
</ul>
<p><strong>SqlSessionFactory：</strong></p>
<ul>
<li>SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在，没有任何理由丢弃它或重新创建另一个实例。 </li>
<li>其很像一个数据库连接池。</li>
<li>最简单的就是使用单例模式或者静态单例模式。</li>
</ul>
<p><strong>SqlSession：</strong></p>
<ul>
<li>就像连接到连接池的一个请求</li>
<li>每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的，因此是不能被共享的，所以它的最佳的作用域是请求或方法作用域。</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/20726a9.png" alt="image-20200723212754942"></p>
<p>这里面的每一个Mapper，就代表一个具体的业务！</p>
<h1 id="5、解决属性名和字段名不一致的问题："><a href="#5、解决属性名和字段名不一致的问题：" class="headerlink" title="5、解决属性名和字段名不一致的问题："></a>5、解决属性名和字段名不一致的问题：</h1><p>数据库中的字段：</p>
<p><img src="http://cdn.rongshen2020.com/20726a10.png" alt="image-20200723204731043"></p>
<p>当你的实体类pojo如果和数据库中的字段不一致时。</p>
<p>例如：你在实体类里面将数据库的pwd写成password，那么有可能查出的user里面password&#x3D;null。</p>
<p><img src="http://cdn.rongshen2020.com/20726a11.png" alt="image-20200724073143227"></p>
<p><strong>解决方法：</strong></p>
<h2 id="5-1、起别名"><a href="#5-1、起别名" class="headerlink" title="5.1、起别名"></a>5.1、起别名</h2><pre><code class="java">select id,name,pwd as password from mybatistest.user;
</code></pre>
<h2 id="5-2、resultMap："><a href="#5-2、resultMap：" class="headerlink" title="5.2、resultMap："></a>5.2、resultMap：</h2><p>结果集映射。</p>
<pre><code class="java">id   name   pwd
id   name   password
</code></pre>
<p>使用方法：</p>
<p><img src="http://cdn.rongshen2020.com/20726a12.png" alt="image-20200724074046862"></p>
<pre><code class="java">&lt;resultMap id=&quot;userResultMap&quot; type=&quot;User&quot;&gt;
  &lt;id property=&quot;id&quot; column=&quot;user_id&quot; /&gt;
  &lt;result property=&quot;username&quot; column=&quot;user_name&quot;/&gt;
  &lt;result property=&quot;password&quot; column=&quot;hashed_password&quot;/&gt;
&lt;/resultMap&gt;
    
&lt;select id=&quot;selectUsers&quot; resultMap=&quot;userResultMap&quot;&gt;
  select user_id, user_name, hashed_password from some_table where id = #&#123;id&#125;
&lt;/select&gt;
</code></pre>
<h1 id="6、日志"><a href="#6、日志" class="headerlink" title="6、日志"></a>6、日志</h1><h2 id="6-1、日志工厂："><a href="#6-1、日志工厂：" class="headerlink" title="6.1、日志工厂："></a>6.1、日志工厂：</h2><p>如果一个数据库操作出现了异常，我们需要排除。所以日志就是最好的助手。</p>
<p>曾经的实现方法：sout、debug。</p>
<p>现在的方法：日志工厂。</p>
<p><img src="http://cdn.rongshen2020.com/20726a13.png" alt="image-20200724093712912"></p>
<ul>
<li>SLF4J</li>
<li>LOG4J【掌握】</li>
<li>LOG4J2</li>
<li>JDK_LOGGING</li>
<li>COMMONS_LOGGING</li>
<li>STDOUT_LOGGING【掌握】</li>
<li>NO_LOGGING</li>
</ul>
<p>在mybatis中具体使用哪一种日志实现，在设置中设定。</p>
<p><strong>STDOUT_LOGGING：标准日志输出</strong></p>
<p>在mybatis核心配置文件中，配置我们的日志！</p>
<pre><code class="java">&lt;settings&gt;
    &lt;setting name=&quot;logImpl&quot; value=&quot;STDOUT_LOGGING&quot;/&gt;
&lt;/settings&gt;
</code></pre>
<p><img src="http://cdn.rongshen2020.com/20726a14.png" alt="image-20200724095336391"></p>
<h2 id="6-2、LOG4J讲解："><a href="#6-2、LOG4J讲解：" class="headerlink" title="6.2、LOG4J讲解："></a>6.2、LOG4J讲解：</h2><p>什么是LOG4J？</p>
<ul>
<li><p>Log4j是Apache的一个开放源代码项目bai，通过du使用Log4j，我们可以控制zhi日志信息输送的目的地是控制台、文件。。。</p>
</li>
<li><p>我们也可以控制每一条日志的输出格式；</p>
</li>
<li><p>通过定义每一条日志信息的级别，我们能够更加细致地控制日志的生成过程。</p>
</li>
<li><p>最令人感兴趣的就是，这些可以通过一个配置文件来灵活地进行配置，而不需要修改应用的代码。</p>
</li>
</ul>
<ol>
<li><p>先导入log4j的包：</p>
<pre><code class="xml">&lt;!-- https://mvnrepository.com/artifact/log4j/log4j --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;log4j&lt;/groupId&gt;
    &lt;artifactId&gt;log4j&lt;/artifactId&gt;
    &lt;version&gt;1.2.17&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
</li>
<li><p>在CLASSPATH下建立log4j.properties。内容如下：</p>
<pre><code class="java">#将等级为DEBUG的日志信息输出到console和file这两个目的地，console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d&#123;yy-MM-dd&#125;】【%c】%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
</code></pre>
</li>
<li><p>在mybatis的核心配置文件中，配置log4j为日志的实现：</p>
<pre><code class="java">&lt;settings&gt;
   &lt;setting name=&quot;logImpl&quot; value=&quot;LOG4J&quot;/&gt;
&lt;/settings&gt;
</code></pre>
</li>
<li><p>log4j的使用，测试运行查询方法：</p>
<p><img src="http://cdn.rongshen2020.com/20726a15.png" alt="image-20200724114147100"></p>
</li>
</ol>
<p><strong>log4j的简单使用：</strong></p>
<ol>
<li><p>在要使用的Log4j的类中，导入包import <code>org.apache.log4j.Logger;</code></p>
</li>
<li><p>日志对象，参数为当前类的class</p>
<pre><code class="java">package com.mucfc;
import org.apache.log4j.Logger;

public class Test &#123;
    private static Logger logger = Logger.getLogger(Test.class);  
 
    public static void main(String[] args) &#123;  
        logger.debug(&quot;This is debug message.&quot;); 
        logger.info(&quot;This is info message.&quot;);   
        logger.error(&quot;This is error message.&quot;);  
    &#125;  
 
&#125;
</code></pre>
</li>
<li><p>日志级别：</p>
<pre><code class="java">logger.debug(&quot;This is debug message.&quot;); 
logger.info(&quot;This is info message.&quot;);   
logger.error(&quot;This is error message.&quot;);  
</code></pre>
</li>
</ol>
<h1 id="7、分页"><a href="#7、分页" class="headerlink" title="7、分页"></a>7、分页</h1><p><strong>思考：为什么要分页？</strong></p>
<ul>
<li>减少数据的处理量</li>
</ul>
<h2 id="7-1、使用Limit分页："><a href="#7-1、使用Limit分页：" class="headerlink" title="7.1、使用Limit分页："></a>7.1、使用Limit分页：</h2><p>sql语句：<code>select * from user limit startIndex,pageSize; </code></p>
<p>数据库的下标也是从0开始的。假设：</p>
<pre><code class="java">select * from user limit 0,2;
select * from user limit 2,2;
.....
</code></pre>
<h2 id="7-2、RowBounds分页："><a href="#7-2、RowBounds分页：" class="headerlink" title="7.2、RowBounds分页："></a>7.2、RowBounds分页：</h2><p>不建议使用。</p>
<h2 id="7-3、分页插件："><a href="#7-3、分页插件：" class="headerlink" title="7.3、分页插件："></a>7.3、分页插件：</h2><h1 id="8、使用注解开发"><a href="#8、使用注解开发" class="headerlink" title="8、使用注解开发"></a>8、使用注解开发</h1><ol>
<li><p>注解在接口上实现：</p>
<pre><code class="JAVA">//获取所有的用户
@Select(&quot;select * from user&quot;)
List&lt;User&gt; getUserList();
</code></pre>
</li>
<li><p>需要在mybatis-config.xml核心配置文件中绑定接口：</p>
<pre><code class="java">&lt;!--绑定接口--&gt;
&lt;mappers&gt;
    &lt;mapper class=&quot;com.aaron.dao.UserDao&quot;/&gt;
&lt;/mappers&gt;
</code></pre>
</li>
</ol>
<p>本质：反射机制。</p>
<p>底层：动态代理。</p>
<h2 id="8-1、CRUD："><a href="#8-1、CRUD：" class="headerlink" title="8.1、CRUD："></a>8.1、CRUD：</h2><pre><code class="java">//根据id和name查询用户
@Select(&quot;select * from user where id = #&#123;id&#125; and name = #&#123;name&#125;&quot;)
User getUserBy(@Param(&quot;id&quot;) int id, @Param(&quot;name&quot;) String name);
</code></pre>
<ul>
<li>关于@Param()注解：<ul>
<li>基本类型的参数或者String类型，需要加上。</li>
<li>引用类型不需要加。</li>
<li>如果只有一个基本类型的话，可以忽略，但是建议大家都加上。</li>
<li>我们在sql中引用的就是我们这里的@Param(“”)中设定的属性名。</li>
</ul>
</li>
</ul>
<h1 id="9、Lombok的使用："><a href="#9、Lombok的使用：" class="headerlink" title="9、Lombok的使用："></a>9、Lombok的使用：</h1><p>Lombok项目是一个Java库，它会自动插入编辑器和构建工具中，Lombok提供了一组有用的注释，用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净，简洁且易于维护的Java类。Lombok也存在一定风险，在一些开发工具商店中没有Project Lombok支持选择。 IDE和JDK升级存在破裂的风险，并且围绕项目的目标和实施存在争议。 </p>
<ol>
<li><p>在IDEA中安装lombok的插件。</p>
</li>
<li><p>在项目中导入lombok的jar包。</p>
<pre><code class="java">&lt;!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
    &lt;artifactId&gt;lombok&lt;/artifactId&gt;
    &lt;version&gt;1.18.12&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
</li>
<li><p>lombok的注解：</p>
<pre><code class="java">@Setter ：注解在类或字段，注解在类时为所有字段生成setter方法，注解在字段上时只为该字段生成setter方法。
@Getter ：使用方法同上，区别在于生成的是getter方法。
@ToString ：注解在类，添加toString方法。
@EqualsAndHashCode： 注解在类，生成hashCode和equals方法。
@NoArgsConstructor： 注解在类，生成无参的构造方法。
@RequiredArgsConstructor： 注解在类，为类中需要特殊处理的字段生成构造方法，比如final和被@NonNull注解的字段。
@AllArgsConstructor： 注解在类，生成包含类中所有字段的构造方法。
@Data： 注解在类，生成setter/getter、equals、canEqual、hashCode、toString方法，如为final属性，则不会为该属性生成setter方法。
@Slf4j： 注解在类，生成log变量，严格意义来说是常量。
</code></pre>
</li>
</ol>
<h1 id="10、多对一与一对多"><a href="#10、多对一与一对多" class="headerlink" title="10、多对一与一对多"></a>10、多对一与一对多</h1><p><strong>联表查询。</strong></p>
<p>多个学生对应一个老师，老师的id对应学生的tid。</p>
<p>创建这两张表的sql语句：</p>
<pre><code class="sql">CREATE TABLE `teacher` (
    `id` INT(10) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, &#39;秦老师&#39;);

CREATE TABLE `student` (
    `id` INT(10) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    `tid` INT(10) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `fktid` (`tid`),
    CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8
    
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (&#39;1&#39;, &#39;小明&#39;, &#39;1&#39;);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (&#39;2&#39;, &#39;小红&#39;, &#39;1&#39;);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (&#39;3&#39;, &#39;小张&#39;, &#39;1&#39;);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (&#39;4&#39;, &#39;小李&#39;, &#39;1&#39;);
INSERT INTO `student` (`id`, `name`, `tid`) VALUES (&#39;5&#39;, &#39;小王&#39;, &#39;1&#39;);
</code></pre>
<p><img src="http://cdn.rongshen2020.com/20726a16.png" alt="image-20200725100251765"></p>
<ul>
<li><p>如果要查询所有的学生表，已经关联的所有老师：</p>
<pre><code class="java">select s.id s.name t.id t.name from student s,teacher t where s.tid = t.id;
</code></pre>
</li>
</ul>
<p>例如如下的两张表：</p>
<p><img src="http://cdn.rongshen2020.com/20726a17.png" alt="image-20200725113252815"></p>
<p><img src="http://cdn.rongshen2020.com/20726a18.png" alt="image-20200725113338525"></p>
<ul>
<li>student表的tid对应teacher表的id。那么我想实现如下的查询结果该如何实现。</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/20726a19.png" alt="image-20200725113439096"></p>
<h2 id="10-1、多对一处理："><a href="#10-1、多对一处理：" class="headerlink" title="10.1、多对一处理："></a>10.1、多对一处理：</h2><h3 id="10-1-1、方式1，类似于子查询："><a href="#10-1-1、方式1，类似于子查询：" class="headerlink" title="10.1.1、方式1，类似于子查询："></a>10.1.1、方式1，类似于子查询：</h3><ul>
<li><p>实体类：</p>
<pre><code>package com.aaron.pojo;

public class Student &#123;
    private int id;
    private String name;
    //学生需要关联一个老师
    private Teacher teacher;

    public Student() &#123;
    &#125;

    public Student(int id, String name, Teacher teacher) &#123;
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    &#125;

    public int getId() &#123;
        return id;
    &#125;

    public void setId(int id) &#123;
        this.id = id;
    &#125;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    public Teacher getTeacher() &#123;
        return teacher;
    &#125;

    public void setTeacher(Teacher teacher) &#123;
        this.teacher = teacher;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Student&#123;&quot; +
                &quot;id=&quot; + id +
                &quot;, name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, teacher=&quot; + teacher +
                &#39;&#125;&#39;;
    &#125;
&#125;
```

```java
package com.aaron.pojo;

public class Teacher &#123;
    private int id;
    private String name;

    public Teacher(int id, String name) &#123;
        this.id = id;
        this.name = name;
    &#125;

    public Teacher() &#123;
    &#125;

    public int getId() &#123;
        return id;
    &#125;

    public void setId(int id) &#123;
        this.id = id;
    &#125;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Teacher&#123;&quot; +
                &quot;id=&quot; + id +
                &quot;, name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;
&#125;
```
</code></pre>
</li>
<li><p>StudentMapper.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;
&lt;mapper namespace=&quot;com.aaron.dao.StudentMapper&quot;&gt;
    &lt;select id=&quot;getStudentList&quot; resultMap=&quot;StudentTeacher&quot;&gt;
        select * from student;
    &lt;/select&gt;
    &lt;select id=&quot;getTeacher&quot; resultType=&quot;com.aaron.pojo.Teacher&quot;&gt;
        select * from teacher where id = #&#123;tid&#125;
    &lt;/select&gt;

    &lt;resultMap id=&quot;StudentTeacher&quot; type=&quot;com.aaron.pojo.Student&quot;&gt;
        &lt;result property=&quot;id&quot; column=&quot;id&quot;&gt;&lt;/result&gt;
        &lt;result property=&quot;name&quot; column=&quot;name&quot;/&gt;
        &lt;!--对于复杂的属性：对象：association。集合：collection。--&gt;
        &lt;association property=&quot;teacher&quot; column=&quot;tid&quot; javaType=&quot;com.aaron.pojo.Teacher&quot; select=&quot;getTeacher&quot;/&gt;
    &lt;/resultMap&gt;
&lt;/mapper&gt;
</code></pre>
</li>
<li><p>以上的步骤很像子查询处理。</p>
<p><img src="http://cdn.rongshen2020.com/20726a20.png" alt="image-20200725121132359"></p>
</li>
</ul>
<h3 id="10-1-2、方式2，按照结果嵌套查询："><a href="#10-1-2、方式2，按照结果嵌套查询：" class="headerlink" title="10.1.2、方式2，按照结果嵌套查询："></a>10.1.2、方式2，按照结果嵌套查询：</h3><ul>
<li><p>在StudentMapper.xml文件中：</p>
<pre><code class="java">&lt;!--按照结果嵌套查询--&gt;
&lt;select id=&quot;getStudentList2&quot; resultMap=&quot;StudentTeacher2&quot;&gt;
    select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid = t.id;
&lt;/select&gt;
&lt;resultMap id=&quot;StudentTeacher2&quot; type=&quot;com.aaron.pojo.Student&quot;&gt;
    &lt;result property=&quot;id&quot; column=&quot;sid&quot;/&gt;
    &lt;result property=&quot;name&quot; column=&quot;sname&quot;/&gt;
    &lt;association property=&quot;teacher&quot; javaType=&quot;com.aaron.pojo.Teacher&quot;&gt;
        &lt;result property=&quot;name&quot; column=&quot;tname&quot;/&gt;
    &lt;/association&gt;
&lt;/resultMap&gt;
</code></pre>
</li>
</ul>
<p><img src="http://cdn.rongshen2020.com/20726a21.png" alt="image-20200725120745107"></p>
<h2 id="10-2、一对多处理："><a href="#10-2、一对多处理：" class="headerlink" title="10.2、一对多处理："></a>10.2、一对多处理：</h2><ul>
<li><p>sql查询语句：</p>
<pre><code class="java">select t.id,t.name tname,s.id sid,s.name sname from student s,teacher t where s.tid = t.id;
</code></pre>
</li>
<li><p>实体类：</p>
<pre><code class="java">package com.aaron.pojo;

public class Student &#123;
    private int id;
    private String name;
    private int tid;

    public Student(int id, String name, int tid) &#123;
        this.id = id;
        this.name = name;
        this.tid = tid;
    &#125;

    public Student() &#123;
    &#125;

    public int getId() &#123;
        return id;
    &#125;

    public void setId(int id) &#123;
        this.id = id;
    &#125;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    public int getTid() &#123;
        return tid;
    &#125;

    public void setTid(int tid) &#123;
        this.tid = tid;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Student&#123;&quot; +
                &quot;id=&quot; + id +
                &quot;, name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, tid=&quot; + tid +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
<pre><code class="java">package com.aaron.pojo;

import java.util.List;

public class Teacher &#123;
    private int id;
    private String name;
    //一个老师拥有多个学生
    Student students;

    public Teacher() &#123;
    &#125;

    public Teacher(int id, String name, Student students) &#123;
        this.id = id;
        this.name = name;
        this.students = students;
    &#125;

    public int getId() &#123;
        return id;
    &#125;

    public void setId(int id) &#123;
        this.id = id;
    &#125;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    public Student getStudents() &#123;
        return students;
    &#125;

    public void setStudents(Student students) &#123;
        this.students = students;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;Teacher&#123;&quot; +
                &quot;id=&quot; + id +
                &quot;, name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, students=&quot; + students +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
</li>
<li><p>TeacherMapper.xml：</p>
<pre><code class="java"> &lt;!--结果嵌套查询--&gt;
    &lt;select id=&quot;getTeacher&quot; resultMap=&quot;TeacherStudent&quot;&gt;
        select t.id,t.name,s.id,s.name,s.tid from student s,teacher t
        where s.tid = t.id and t.id = #&#123;id&#125;;
    &lt;/select&gt;
    &lt;resultMap id=&quot;TeacherStudent&quot; type=&quot;com.aaron.pojo.Teacher&quot;&gt;
        &lt;result property=&quot;id&quot; column=&quot;t.id&quot;/&gt;
        &lt;result property=&quot;name&quot; column=&quot;t.name&quot;/&gt;
        &lt;collection property=&quot;students&quot; ofType=&quot;com.aaron.pojo.Student&quot;&gt;
            &lt;result property=&quot;id&quot; column=&quot;s.id&quot;/&gt;
            &lt;result property=&quot;name&quot; column=&quot;s.name&quot;/&gt;
            &lt;result property=&quot;tid&quot; column=&quot;s.tid&quot;/&gt;
        &lt;/collection&gt;
    &lt;/resultMap&gt;
</code></pre>
</li>
</ul>
<h2 id="10-3、小结："><a href="#10-3、小结：" class="headerlink" title="10.3、小结："></a>10.3、小结：</h2><ol>
<li>关联-associate【多对一】</li>
<li>集合-collation【一对多】</li>
<li>javaType和ofType</li>
</ol>
<h1 id="11、动态SQL"><a href="#11、动态SQL" class="headerlink" title="11、动态SQL"></a>11、动态SQL</h1><p>什么是动态SQL：动态Sql就是指根据不同的条件生成不同的SQL语句。</p>
<pre><code class="java">CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT &#39;博客id&#39;,
`title` VARCHAR(100) NOT NULL COMMENT &#39;博客标题&#39;,
`author` VARCHAR(30) NOT NULL COMMENT &#39;博客作者&#39;,
`create_time` DATETIME NOT NULL COMMENT &#39;创建时间&#39;,
`views` INT(30) NOT NULL COMMENT &#39;浏览量&#39;
)ENGINE=INNODB DEFAULT CHARSET=utf8
</code></pre>
<h2 id="11-1、if语句："><a href="#11-1、if语句：" class="headerlink" title="11.1、if语句："></a>11.1、if语句：</h2><ul>
<li><p>BlogMapper.xml：</p>
<pre><code class="java">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;

&lt;mapper namespace=&quot;com.aaron.dao.BlogMapper&quot;&gt;
    &lt;select id=&quot;getBlogList&quot; parameterType=&quot;map&quot; resultType=&quot;com.aaron.pojo.Blog&quot;&gt;
        select * from mybatistest.blog where 1 = 1
        &lt;if test=&quot;title != null&quot;&gt;and title = #&#123;title&#125;&lt;/if&gt;
        &lt;if test=&quot;author != null&quot;&gt;and author = #&#123;author&#125;&lt;/if&gt;
    &lt;/select&gt;
&lt;/mapper&gt;
</code></pre>
</li>
<li><p>test.java</p>
<pre><code class="java">package com.aaron.dao;

import com.aaron.pojo.Blog;
import com.aaron.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.HashMap;
import java.util.List;

public class BlogMapperTest &#123;
    public static void main(String[] args) &#123;
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();
        map.put(&quot;title&quot;,&quot;红楼梦&quot;);
        map.put(&quot;author&quot;,&quot;曹雪芹&quot;);
        List&lt;Blog&gt; blogList = blogMapper.getBlogList(map);
        for (Blog blog : blogList) &#123;
            System.out.println(blog);
        &#125;
        sqlSession.close();
    &#125;
&#125;
</code></pre>
</li>
</ul>
<h2 id="11-2、常用标签："><a href="#11-2、常用标签：" class="headerlink" title="11.2、常用标签："></a>11.2、常用标签：</h2><ul>
<li><p>choose、when、otherwise：</p>
<pre><code class="java">&lt;select id=&quot;findActiveBlogLike&quot;
     resultType=&quot;Blog&quot;&gt;
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  &lt;choose&gt;
    &lt;when test=&quot;title != null&quot;&gt;
      AND title like #&#123;title&#125;
    &lt;/when&gt;
    &lt;when test=&quot;author != null and author.name != null&quot;&gt;
      AND author_name like #&#123;author.name&#125;
    &lt;/when&gt;
    &lt;otherwise&gt;
      AND featured = 1
    &lt;/otherwise&gt;
  &lt;/choose&gt;
&lt;/select&gt;
</code></pre>
</li>
<li><p>trim、where、set：</p>
<pre><code class="java">&lt;select id=&quot;findActiveBlogLike&quot;
     resultType=&quot;Blog&quot;&gt;
  SELECT * FROM BLOG
  &lt;where&gt;
    &lt;if test=&quot;state != null&quot;&gt;
         state = #&#123;state&#125;
    &lt;/if&gt;
    &lt;if test=&quot;title != null&quot;&gt;
        AND title like #&#123;title&#125;
    &lt;/if&gt;
    &lt;if test=&quot;author != null and author.name != null&quot;&gt;
        AND author_name like #&#123;author.name&#125;
    &lt;/if&gt;
  &lt;/where&gt;
&lt;/select&gt;
</code></pre>
<pre><code class="java">&lt;update id=&quot;updateAuthorIfNecessary&quot;&gt;
  update Author
    &lt;set&gt;
      &lt;if test=&quot;username != null&quot;&gt;username=#&#123;username&#125;,&lt;/if&gt;
      &lt;if test=&quot;password != null&quot;&gt;password=#&#123;password&#125;,&lt;/if&gt;
      &lt;if test=&quot;email != null&quot;&gt;email=#&#123;email&#125;,&lt;/if&gt;
      &lt;if test=&quot;bio != null&quot;&gt;bio=#&#123;bio&#125;&lt;/if&gt;
    &lt;/set&gt;
  where id=#&#123;id&#125;
&lt;/update&gt;
</code></pre>
<pre><code class="java">&lt;trim prefix=&quot;WHERE&quot; prefixOverrides=&quot;AND |OR &quot;&gt;
  ...
&lt;/trim&gt;
    
&lt;trim prefix=&quot;SET&quot; suffixOverrides=&quot;,&quot;&gt;
  ...
&lt;/trim&gt;    
</code></pre>
</li>
</ul>
<h2 id="11-3、sql片段："><a href="#11-3、sql片段：" class="headerlink" title="11.3、sql片段："></a>11.3、sql片段：</h2><p>我们会将一些公用的片段抽取出来，实现复用。</p>
<pre><code class="java">&lt;sql id=&quot;&quot;&gt;
    &lt;if&gt;.....
&lt;/sql&gt;
        
底下引用时，只需要使用&lt;include refid=&quot;&quot;&gt;标签就可以导入该片段。
</code></pre>
<h2 id="11-4、foreach："><a href="#11-4、foreach：" class="headerlink" title="11.4、foreach："></a>11.4、foreach：</h2><ul>
<li>动态 SQL 的另一个常见使用场景是对集合进行遍历（尤其是在构建 IN 条件语句的时候）。比如：</li>
</ul>
<pre><code class="java">&lt;select id=&quot;selectPostIn&quot; resultType=&quot;domain.blog.Post&quot;&gt;
  SELECT *
  FROM POST P
  WHERE ID in
  &lt;foreach item=&quot;item&quot; index=&quot;index&quot; collection=&quot;list&quot;
      open=&quot;(&quot; separator=&quot;,&quot; close=&quot;)&quot;&gt;
        #&#123;item&#125;
  &lt;/foreach&gt;
&lt;/select&gt;
</code></pre>
<h1 id="12、缓存"><a href="#12、缓存" class="headerlink" title="12、缓存"></a>12、缓存</h1><blockquote>
<p>查询：连接数据库耗资源。一次查询的结果，给他暂存在一个可以直接取到的地方——》内存，缓存。我们再次查到相同数据的时候，直接走缓存，就不用走数据库了。</p>
<p>参考文档：<a target="_blank" rel="noopener" href="https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache">https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache</a></p>
</blockquote>
<p><img src="http://cdn.rongshen2020.com/20726a22.png" alt="image-20200726094620034"></p>
<p><img src="http://cdn.rongshen2020.com/20726a23.png" alt="image-20200726094637092"></p>
<h2 id="12-1、一级缓存："><a href="#12-1、一级缓存：" class="headerlink" title="12.1、一级缓存："></a>12.1、一级缓存：</h2><h2 id="12-2、二级缓存："><a href="#12-2、二级缓存：" class="headerlink" title="12.2、二级缓存："></a>12.2、二级缓存：</h2><p>MyBatis 内置了一个强大的事务性查询缓存机制，它可以非常方便地配置和定制。 为了使它更加强大而且易于配置，我们对 MyBatis 3 中的缓存实现进行了许多改进。</p>
<p>默认情况下，只启用了本地的会话缓存，它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存，只需要在你的 SQL 映射文件中添加一行：</p>
<p><img src="http://cdn.rongshen2020.com/20726a24.png" alt="image-20200726103118359"></p>
<pre><code>&lt;cache/&gt;
</code></pre>
<h2 id="12-3、自定义缓存："><a href="#12-3、自定义缓存：" class="headerlink" title="12.3、自定义缓存："></a>12.3、自定义缓存：</h2><p>EhCache 是一个<code>纯Java</code>的进程内<code>缓存框架</code>，具有快速、精干等特点，是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有<code>内存</code>和<code>磁盘</code>存储，缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。</p>
<p>介绍链接：<a target="_blank" rel="noopener" href="https://www.jianshu.com/p/154c82073b07">https://www.jianshu.com/p/154c82073b07</a></p>
<h2 id="12-4、redis做缓存："><a href="#12-4、redis做缓存：" class="headerlink" title="12.4、redis做缓存："></a>12.4、redis做缓存：</h2>
      
    </div>
    
    
    <div class="article-category">
      
        <b>Categories:</b>
        <a class="article-category-link" href="/categories/%E6%A1%86%E6%9E%B6/">框架</a>
      
      
        <br/>
      
      
        <b>Tags:</b>
        <a class="article-tag-none-link" href="/tags/mybatis/" rel="tag">mybatis</a>
      
    </div>
    
    
  </div>
</article>

  
<nav id="article-nav" class="article-nav">
  
    <a href="/2020/07/26/Spring5%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" id="article-nav-newer" class="article-nav-link-wrap newer">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          Spring5学习笔记
        
      </div>
    </a>
  
  
    <a href="/2020/06/30/%E2%80%9C%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%8A%E9%83%A8%E7%BD%B2%E4%B8%80%E4%B8%AA%E5%89%8D%E5%90%8E%E7%AB%AF%E5%88%86%E7%A6%BB%E9%A1%B9%E7%9B%AE%EF%BC%88%E8%8B%A5%E4%BE%9D-ruoyi%EF%BC%89%E5%AE%9E%E9%AA%8C%E2%80%9D/" id="article-nav-older" class="article-nav-link-wrap older">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">
        
          “虚拟机上部署一个前后端分离项目（若依-ruoyi）实验”
        
      </div>
    </a>
  
</nav>






    </div>
  </div>
  




<div id="settings-container">
  <div id="dark-mode">dark</div>
  <div id="sans-font">sans</div>
</div>
<script type="text/javascript">
let d=document,r=d.documentElement.style,f=r.setProperty.bind(r),l=localStorage,s=l.getItem('s')||(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches),n=l.getItem('n'),m=d.getElementById("dark-mode"),b=()=>{f('--bg-color','#fafafa');f('--code-bg-color','#f4f4f4');f('--text-color','#212121');f('--secondary-color','#808080');f('--tertiary-color','#b0b0b0');f('--link-color','#b5c8cf');f('--link-hover-color','#618794');f('--link-bg-color','#dae4e7');f('--selection-color','#dae4e7');m.innerHTML="dark"},c=()=>{f('--bg-color','#212121');f('--code-bg-color','#292929');f('--text-color','#fff');f('--secondary-color','#c0c0c0');f('--tertiary-color','#6e6e6e');f('--link-color','#4d6b75');f('--link-hover-color','#96b1bb');f('--link-bg-color','#5d828e');f('--selection-color','#acc1c9');m.innerHTML="light"},o=d.getElementById("sans-font"),e=()=>{f('--body-stack','"Lora", "Georgia", "Times New Roman", serif');o.innerHTML="sans"},g=()=>{f('--body-stack','"Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "Verdana", sans-serif');o.innerHTML="serif"};m.onclick=()=>{if(s==2){s=1;l.setItem('s',s);c()}else{s=2;l.setItem('s',s);b()}};o.onclick=()=>{if(n==2){n=1;l.setItem('n',n);g()}else{n=2;l.setItem('n',n);e()}};if(!s){s=2;l.setItem('s',2)};if(s==1){c()};if(!n){n=2;l.setItem('n',2)};if(n==1){g()};
</script>




</body>
</html>
